BITS 32
%include "macrosmodoprotegido.mac"

extern fin_intr_pic1
extern ULTIMA_TAREA_ASM
extern TAREA1_ASM
extern obtener_virtual_libre
extern pagina_libre_usuario
extern mapear_pagina
extern cambiar_a_cr3_kernel
extern volver_a_cr3_usuario
extern recuperar_cr3_usuario


_eax: db 'EAX    '
eax_len: equ $ - _eax

_ebx: db 'EBX    '
ebx_len: equ $ - _ebx

_ecx: db 'ECX    '
ecx_len: equ $ - _ecx

_edx: db 'EDX    '
edx_len: equ $ - _edx

_esi: db 'ESI    '
esi_len: equ $ - _esi

_edi: db 'EDI    '
edi_len: equ $ - _edi

_ebp: db 'EBP    '
ebp_len: equ $ - _ebp

_esp: db 'ESP    '
esp_len: equ $ - _esp

_cr0: db 'CR0    '
cr0_len: equ $ - _cr0


_cr2: db 'CR2    '
cr2_len: equ $ - _cr2

_cr3: db 'CR3    '
cr3_len: equ $ - _cr3

_cr4: db 'CR4    '
cr4_len: equ $ - _cr4

eflags: db 'EFLAGS '
eflags_len: equ $ - eflags


_cs: db 'CS     '
cs_len: equ $ - _cs

_ds: db 'DS     '
ds_len: equ $ - _ds

_es: db 'ES     '
es_len: equ $ - _es

_fs: db 'FS     '
fs_len: equ $ - _fs

_gs: db 'GS     '
gs_len: equ $ - _gs


_ss: db 'SS     '
ss_len: equ $ - _ss

_stack: db 'Stack:     '
stack_len: equ $ - _stack

buffer_hex: dq 0
eax_temp: dd 0



;La hacemos macro para no modificar el stack, dado que queremos imprimir los registros
;tal cual estan en el momento del error.
col1_dump equ 1
col2_dump equ 20
fil1_dump equ 4
fil2_dump equ 4

info_reg:
	IMPRIMIR_TEXTO $_eax, eax_len, 01000111b, fil1_dump, col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, fil1_dump, (col1_dump+eax_len)

	IMPRIMIR_TEXTO $_ebx, ebx_len, 01000111b, (fil1_dump+1), col1_dump
	DWORD_TO_HEX ebx, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+1), (col1_dump+ebx_len)	
	
	IMPRIMIR_TEXTO $_ecx, ecx_len, 01000111b, (fil1_dump+2), col1_dump
	DWORD_TO_HEX ecx, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+2), (col1_dump+ecx_len)

	IMPRIMIR_TEXTO $_edx, edx_len, 01000111b, (fil1_dump+3), col1_dump
	DWORD_TO_HEX edx, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+3), (col1_dump+edx_len)

	IMPRIMIR_TEXTO $_esi, esi_len, 01000111b, (fil1_dump+4), col1_dump
	DWORD_TO_HEX esi, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+4), (col1_dump+esi_len)

	IMPRIMIR_TEXTO $_edi, edi_len, 01000111b, (fil1_dump+5), col1_dump
	DWORD_TO_HEX edi, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+5), (col1_dump+edi_len)

	IMPRIMIR_TEXTO $_ebp, ebp_len, 01000111b, (fil1_dump+6), col1_dump
	DWORD_TO_HEX ebp, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+6), (col1_dump+ebp_len)
	
	mov [eax_temp], eax
	
	IMPRIMIR_TEXTO $_esp, esp_len, 01000111b, (fil1_dump+7), col1_dump
	lea eax,[esp+4]			; usamos lea para sumar 4 por el call sin modificar eflags
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+7), (col1_dump+esp_len)
	
	mov eax,cr0
	IMPRIMIR_TEXTO $_cr0, cr0_len, 01000111b, (fil1_dump+9), col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+9), (col1_dump+cr0_len)
	
	mov eax,cr2	
	IMPRIMIR_TEXTO $_cr2, cr2_len, 01000111b, (fil1_dump+10), col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+10), (col1_dump+cr2_len)
	
	mov eax,cr3	
	IMPRIMIR_TEXTO $_cr3, cr3_len, 01000111b, (fil1_dump+11), col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+11), (col1_dump+cr3_len)

	mov eax,cr4	
	IMPRIMIR_TEXTO $_cr4, cr4_len, 01000111b, (fil1_dump+12), col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+12), (col1_dump+cr4_len)

	mov eax,0
	lahf
	IMPRIMIR_TEXTO $eflags, eflags_len, 01000111b, (fil1_dump+14), col1_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil1_dump+14), (col1_dump+eflags_len)

	mov eax,0
	mov ax,cs
	IMPRIMIR_TEXTO $_cs, cs_len, 01000111b, fil2_dump, col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, fil2_dump, (col2_dump+cs_len)
	
	mov eax,0
	mov ax,ds
	IMPRIMIR_TEXTO $_ds, ds_len, 01000111b, (fil2_dump+1), col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+1), (col2_dump+ds_len)

	mov eax,0
	mov ax,es
	IMPRIMIR_TEXTO $_es, es_len, 01000111b, (fil2_dump+2), col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+2), (col2_dump+es_len)

	mov eax,0
	mov ax,fs
	IMPRIMIR_TEXTO $_fs, fs_len, 01000111b, (fil2_dump+3), col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+3), (col2_dump+fs_len)

	mov eax,0
	mov ax,gs
	IMPRIMIR_TEXTO $_gs, gs_len, 01000111b, (fil2_dump+4), col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+4), (col2_dump+gs_len)
	
	mov eax,0
	mov ax,ss
	IMPRIMIR_TEXTO $_ss, ss_len, 01000111b, (fil2_dump+5), col2_dump
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+5), (col2_dump+ss_len)
	
	IMPRIMIR_TEXTO $_stack, stack_len, 01000111b, (fil2_dump+8), col2_dump

	mov eax, [esp+4]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+10), col2_dump
	
	mov eax, [esp+8]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+11), col2_dump

	mov eax, [esp+12]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+12), col2_dump

	mov eax, [esp+16]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+13), col2_dump
	
	mov eax, [esp+20]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+14), col2_dump

	mov eax, [esp+24]
	DWORD_TO_HEX eax, buffer_hex
	IMPRIMIR_TEXTO buffer_hex, 8, 01000111b, (fil2_dump+15), col2_dump
	
	mov eax,[eax_temp]
	ret


global _isr0
_isr0:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int0_len
	MOV ESI, int0
	MOV EDI, 0
	MOV AH, 0x8A
ciclo0:
	LODSB
	STOSW
	LOOP ciclo0
	jmp $

global _isr1
_isr1:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int1_len
	MOV ESI, int1
	MOV EDI, 0
	MOV AH, 0x8A
ciclo1:
	LODSB
	STOSW
	LOOP ciclo1
	jmp $

global _isr2
_isr2:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int2_len
	MOV ESI, int2
	MOV EDI, 0
	MOV AH, 0x8A
ciclo2:
	LODSB
	STOSW
	LOOP ciclo2
	jmp $
	
	
	
	
global _isr3
_isr3:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int3_len
	MOV ESI, int3
	MOV EDI, 0
	MOV AH, 0x8A
ciclo3:
	LODSB
	STOSW
	LOOP ciclo3
	jmp $
	
global _isr4
_isr4:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int4_len
	MOV ESI, int4
	MOV EDI, 0
	MOV AH, 0x8A
ciclo4:
	LODSB
	STOSW
	LOOP ciclo4
	jmp $
	
global _isr5
_isr5:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int5_len
	MOV ESI, int5
	MOV EDI, 0
	MOV AH, 0x8A
ciclo5:
	LODSB
	STOSW
	LOOP ciclo5
	jmp $
	
	
global _isr6
_isr6:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int6_len
	MOV ESI, int6
	MOV EDI, 0
	MOV AH, 0x8A
ciclo6:
	LODSB
	STOSW
	LOOP ciclo6
	jmp $
	
global _isr7
_isr7:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int7_len
	MOV ESI, int7
	MOV EDI, 0
	MOV AH, 0x8A
ciclo7:
	LODSB
	STOSW
	LOOP ciclo7
	jmp $
	
global _isr8
_isr8:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int8_len
	MOV ESI, int8
	MOV EDI, 0
	MOV AH, 0x8A
ciclo8:
	LODSB
	STOSW
	LOOP ciclo8
	jmp $
	
global _isr9
_isr9:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int9_len
	MOV ESI, int9
	MOV EDI, 0
	MOV AH, 0x8A
ciclo9:
	LODSB
	STOSW
	LOOP ciclo9
	jmp $
	
global _isr10
_isr10:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int10_len
	MOV ESI, int10
	MOV EDI, 0
	MOV AH, 0x8A
ciclo10:
	LODSB
	STOSW
	LOOP ciclo10
	jmp $

global _isr11
_isr11:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int11_len
	MOV ESI, int11
	MOV EDI, 0
	MOV AH, 0x8A
ciclo11:
	LODSB
	STOSW
	LOOP ciclo11
	jmp $
	

	
global _isr12
_isr12:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int12_len
	MOV ESI, int12
	MOV EDI, 0
	MOV AH, 0x8A
ciclo12:
	LODSB
	STOSW
	LOOP ciclo12
	jmp $
	
	
	
global _isr13
_isr13:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int13_len
	MOV ESI, int13
	MOV EDI, 0
	MOV AH, 0x8A
ciclo13:
	LODSB
	STOSW
	LOOP ciclo13
	jmp $

	
global _isr14
_isr14:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int14_len
	MOV ESI, int14
	MOV EDI, 0
	MOV AH, 0x8A
ciclo14:
	LODSB
	STOSW
	LOOP ciclo14
	jmp $
	
global _isr15
_isr15:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int15_len
	MOV ESI, int15
	MOV EDI, 0
	MOV AH, 0x8A
ciclo15:
	LODSB
	STOSW
	LOOP ciclo15
	jmp $
	
global _isr16
_isr16:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int16_len
	MOV ESI, int16
	MOV EDI, 0
	MOV AH, 0x8A
ciclo16:
	LODSB
	STOSW
	LOOP ciclo16
	jmp $
	
global _isr17
_isr17:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int17_len
	MOV ESI, int17
	MOV EDI, 0
	MOV AH, 0x8A
ciclo17:
	LODSB
	STOSW
	LOOP ciclo17
	jmp $
	
global _isr18
_isr18:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int18_len
	MOV ESI, int18
	MOV EDI, 0
	MOV AH, 0x8A
ciclo18:
	LODSB
	STOSW
	LOOP ciclo18
	jmp $
	
	
	
global _isr19
_isr19:
	call info_reg
	MOV AX, 0x18
	MOV ES, AX
	MOV AX, 0x08
	MOV DS,AX
	MOV ECX, int19_len
	MOV ESI, int19
	MOV EDI, 0
	MOV AH, 0x8A
ciclo19:
	LODSB
	STOSW
	LOOP ciclo19
	jmp $
	
global _isr32
_isr32:	
   	pushad
	
   	call proximo_reloj
	
	call fin_intr_pic1
	
	; cambio de tarea
	xor eax,eax
	xor ebx,ebx
	str ax	; cargamos el TR actual en ax 
	mov bx,ax
	shr ax,3	; el indice en la tss de la tarea actual 
	inc ax
	
	cmp eax, [ULTIMA_TAREA_ASM]
	jg set_tarea1
	
	add ebx,0x8
	mov [selector],bx
	popad
	jmp far [offset]
	jmp fin
	
set_tarea1:
	
	mov ax,[TAREA1_ASM]
	shl ax,3
	or ax,3
	mov [selector],ax
	popad	
	jmp far [offset]
	; fin cambio de tarea
	
	
fin:
	iret	
	
global _isr33
_isr33:
	    pushad
	    xor eax,eax
	    in al,60h		;leo la tecla
	    cmp al,11		;si es mayor que 11 o menor que 2,
	    jg avisarPIC	;no es un numero.
	    cmp al,2
	    jl avisarPIC
	    dec al
	    mov ebx,10		;acomodo el numero 0 adelante
	    div bl
	    xor ebx,ebx
	    mov bl,ah
	    add bl,0x30		;convierto en ASCII
	    mov [tec_nums],bl
	    mov edx,tec_nums
	    IMPRIMIR_TEXTO edx, 1, 0x09, 24, 39
avisarPIC:
    call fin_intr_pic1
    popad
    iret	

    
%define p_mensaje ecx+8
%define modo ecx+12
%define fila ecx+16
%define columna ecx+20
%define usu_ss ebp+20
%define usu_esp ebp+16
global _isr88
_isr88:
	cli   
	
	push ebp
	mov ebp,esp	
	pushad
	push es
	push fs
	
	mov ax,[usu_ss]
	mov fs,ax
	mov ecx,[usu_esp]
		
	mov ax,0x18
	mov es,ax
	mov eax,80*2
	mov ebx, [fs:fila]
	
	mul ebx
	

	
	mov edx, [fs:p_mensaje]
	
	mov ebx,[fs:columna]
	shl ebx,1
	add eax,ebx
	
	mov esi, eax
	mov ah, [fs:modo]

ciclo_mensaje:	
	cmp byte[edx], 0
	je fin_ciclo
	  
	mov al,[edx]
	mov [es:esi],ax
	add esi,2
	inc edx	
	jmp ciclo_mensaje
	
fin_ciclo:
	pop fs
	pop es
	popad
	pop ebp
	sti
	iret
    
global _isr89
_isr89:
    cli
    call cambiar_a_cr3_kernel
    pushad

    call recuperar_cr3_usuario
    push eax
    call obtener_virtual_libre
    add esp,4
    cmp eax,0
    jne queda_dir_virtual
    mov dword [dir_virtual], 0  ; si no quedan dir. virtuales retornamos 0
    jmp finalizar

queda_dir_virtual:
    mov ebx,eax			; guardo la prox virtual libre

    call pagina_libre_usuario
    				; en eax tengo una pagina libre de usuario

    cmp eax,0
    jne queda_dir_fisica
    mov dword [dir_virtual], 0  ; si no quedan dir. fisicas retornamos 0
    jmp finalizar

queda_dir_fisica:
    push dword 0x00000007	; permisos usuario
    
    push eax			; real libre
    call recuperar_cr3_usuario
    push eax			; cr3 actual
    push ebx			; direccion virtual libre
    call mapear_pagina
    add esp,16
    mov [dir_virtual], ebx

finalizar:
    popad
    mov eax, [dir_virtual]
    call volver_a_cr3_usuario
    sti
    iret    
    
    
    
proximo_reloj:
	pushad
	inc DWORD [isrnumero]
	mov ebx, [isrnumero]
	cmp ebx, 0x4
	jl .ok
		mov DWORD [isrnumero], 0x0
		mov ebx, 0
	.ok:
		add ebx, isrmensaje1
		mov edx, isrmensaje
		IMPRIMIR_TEXTO edx, 6, 0x0A, 24, 73
		IMPRIMIR_TEXTO ebx, 1, 0x0A, 24, 79
	popad
	ret
	
isrmensaje: db 'Clock:'
isrnumero: dd 0x00000000
isrmensaje1: db '|'
isrmensaje2: db '/'
isrmensaje3: db '-'
isrmensaje4: db '\'

int0: db 'ERROR: Division por 0 - Fault'
int0_len: equ $ - int0

int1: db 'ERROR: Reservado - Fault/Trap'
int1_len: equ $ - int1


int2: db 'ERROR: NMI Interrupt - Interrupt'
int2_len: equ $ - int2


int3: db 'ERROR: Breackpoint - Trap'
int3_len: equ $ - int3

int4: db 'ERROR: Overflow - Trap'
int4_len: equ $ - int4

int5: db 'ERROR: BOUND Range Exceeded - Fault'
int5_len: equ $ - int5

int6: db 'ERROR: Invalid Opcode - Fault'
int6_len: equ $ - int6

int7: db 'ERROR: Device Not Available - Fault'
int7_len: equ $ - int7

int8: db 'ERROR: Double Fault - Abort'
int8_len: equ $ - int8

int9: db 'ERROR: Coprocessor Segment Overrun (Reserved) - Fault'
int9_len: equ $ - int9

int10: db 'ERROR: Invalid TSS - Fault'
int10_len: equ $ - int10

int11: db 'ERROR: Segment Not Present - Fault'
int11_len: equ $ - int11

int12: db 'ERROR: Stack-Segment Fault - Fault'
int12_len: equ $ - int12

int13: db 'ERROR: General Protection - Fault'
int13_len: equ $ - int13

int14: db 'ERROR: Page fault - Fault'
int14_len: equ $ - int14

int15: db 'ERROR: Intel Reserved. Do Not Use - Fault'
int15_len: equ $ - int15

int16: db 'ERROR: x87 FPU Floating-Point Error (Math Fault) - Fault'
int16_len: equ $ - int16

int17: db 'ERROR: Aligment Check - Fault'
int17_len: equ $ - int17

int18: db 'ERROR: Machine Check . Abort'
int18_len: equ $ - int18

int19: db 'ERROR: SIMD Floating-Point Exception - Fault'
int19_len: equ $ - int19


tec_nums: db '0'
dir_virtual: dw 0

offset: dd 0
selector: dw 0
